package com.jshcbd.mvp_kt_demo.exception

import android.util.Log
import com.google.gson.JsonParseException
import com.google.gson.JsonSerializer
import org.apache.http.conn.ConnectTimeoutException
import org.json.JSONException
import retrofit2.HttpException
import java.io.NotSerializableException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.text.ParseException
import javax.net.ssl.SSLHandshakeException

class ApiException(throwable: Throwable?, val code: Int) : Exception(throwable) {
    override var message: String?=null

    /*** 约定异常  */
    object ERROR {
        /*** 未知错误  */
        const val UNKNOWN = 1000

        /*** 连接超时  */
        const val TIMEOUT_ERROR = 1001

        /*** 空指针错误  */
        const val NULL_POINTER_EXCEPTION = 1002

        /*** 证书出错  */
        const val SSL_ERROR = 1003

        /*** 类转换错误  */
        const val CAST_ERROR = 1004

        /*** 解析错误  */
        const val PARSE_ERROR = 1005

        /*** 非法数据异常  */
        const val ILLEGAL_STATE_ERROR = 1006
    }

    companion object {
        //对应HTTP的状态码
        private const val UNAUTHORIZED = 401
        private const val FORBIDDEN = 403
        private const val NOT_FOUND = 404
        private const val REQUEST_TIMEOUT = 408
        private const val INTERNAL_SERVER_ERROR = 500
        private const val BAD_GATEWAY = 502
        private const val SERVICE_UNAVAILABLE = 503
        private const val GATEWAY_TIMEOUT = 504
        private const val MY_TAG = "ApiException"
        fun handleException(e: Throwable?): ApiException {
            var e = e
            var throwable = e
            //获取最根源的异常
            while (throwable!!.cause != null) {
                e = throwable
                throwable = throwable.cause
            }
            val ex: ApiException
            Log.w(MY_TAG, "ApiException===>$e")
            //TODO 需要把中文放到strings里面
            return if (e is HttpException) {             //HTTP错误
                val httpException = e
                ex = ApiException(e, httpException.code())
                when (httpException.code()) {
                    UNAUTHORIZED, FORBIDDEN -> {
                    }
                    NOT_FOUND, REQUEST_TIMEOUT, GATEWAY_TIMEOUT, INTERNAL_SERVER_ERROR, BAD_GATEWAY, SERVICE_UNAVAILABLE -> ex.message =
                        "默认网络异常" //均视为网络错误
                    else -> ex.message = "默认网络异常"
                }
                ex
            } else if (e is SocketTimeoutException) {
                ex = ApiException(e, ERROR.TIMEOUT_ERROR)
                ex.message = "网络连接超时，请检查您的网络状态，稍后重试！"
                ex
            } else if (e is ConnectException) {
                ex = ApiException(e, ERROR.TIMEOUT_ERROR)
                ex.message = "网络连接异常，请检查您的网络状态，稍后重试！"
                ex
            } else if (e is ConnectTimeoutException) {
                ex = ApiException(e, ERROR.TIMEOUT_ERROR)
                ex.message = "网络连接超时，请检查您的网络状态，稍后重试！"
                ex
            } else if (e is UnknownHostException) {
                ex = ApiException(e, ERROR.TIMEOUT_ERROR)
                ex.message = "网络连接异常，请检查您的网络状态，稍后重试！"
                ex
            } else if (e is NullPointerException) {
                ex = ApiException(e, ERROR.NULL_POINTER_EXCEPTION)
                ex.message = "空指针异常"
                ex
            } else if (e is SSLHandshakeException) {
                ex = ApiException(e, ERROR.SSL_ERROR)
                ex.message = "证书验证失败"
                ex
            } else if (e is ClassCastException) {
                ex = ApiException(e, ERROR.CAST_ERROR)
                ex.message = "类型转换错误"
                ex
            } else if (e is JsonParseException
                || e is JSONException //            || e instanceof JsonSyntaxException
                || e is JsonSerializer<*>
                || e is NotSerializableException
                || e is ParseException
            ) {
                ex = ApiException(e, ERROR.PARSE_ERROR)
                ex.message = "解析错误"
                ex
            } else if (e is IllegalStateException) {
                ex = ApiException(e, ERROR.ILLEGAL_STATE_ERROR)
                ex.message = e.message!!
                ex
            } else {
                ex = ApiException(e, ERROR.UNKNOWN)
                ex.message = "未知错误"
                ex
            }
        }
    }

    init {
        message = throwable!!.message!!
    }
}